package com.exrobot.module.rbt.service.robottask;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.exrobot.framework.common.util.collection.CollectionUtils;
import com.exrobot.module.rbt.controller.admin.order.vo.OrderRespVO;
import com.exrobot.module.rbt.controller.admin.orderitem.vo.OrderItemRespVO;
import com.exrobot.module.rbt.controller.app.vo.CommonTaskVO;
import com.exrobot.module.rbt.controller.app.vo.MealCodeVO;
import com.exrobot.module.rbt.dal.redis.RbtRedisDAO;
import com.exrobot.module.rbt.dal.redis.RedisTaskField;
import com.exrobot.module.rbt.enums.RbtOrderStatusEnum;
import com.exrobot.module.rbt.enums.RbtTaskStatusEnum;
import com.exrobot.module.rbt.enums.RbtTaskTypeEnum;
import com.exrobot.module.rbt.service.mqtt.MqttMessageService;
import com.exrobot.module.rbt.service.order.OrderService;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import com.exrobot.module.rbt.controller.admin.robottask.vo.*;
import com.exrobot.module.rbt.dal.dataobject.robottask.RobotTaskDO;
import com.exrobot.framework.common.pojo.PageResult;
import com.exrobot.framework.common.util.object.BeanUtils;

import com.exrobot.module.rbt.dal.mysql.robottask.RobotTaskMapper;

import static com.exrobot.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.exrobot.framework.common.util.collection.CollectionUtils.convertList;
import static com.exrobot.module.rbt.enums.ErrorCodeConstants.*;

/**
 * 机器人任务 Service 实现类
 *
 * @author 超级管理员
 */
@Slf4j
@Service
@Validated
public class RobotTaskServiceImpl implements RobotTaskService {

    @Resource
    private RobotTaskMapper robotTaskMapper;

    @Lazy
    @Resource
    private MqttMessageService mqttMessageService;

    @Lazy
    @Resource
    private OrderService orderService;

    @Resource
    private RbtRedisDAO rbtRedisDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RobotTaskDO createRobotTask(RobotTaskSaveReqVO createReqVO) {
        RobotTaskDO robotTask = BeanUtils.toBean(createReqVO, RobotTaskDO.class);
        String taskNo = rbtRedisDAO.generateTaskNo();
        robotTask.setTaskNo(taskNo);
        if (createReqVO.getStatus() == null) {
            robotTask.setStatus(RbtTaskStatusEnum.UNEXEC.getVal());
        }
        //同样的任务 任务状态设置为调度中
//        if(!isExitTask(createReqVO.getRobotSn()) || validateSameTask(createReqVO.getRobotSn(),createReqVO.getTaskType())) {
//            robotTask.setStatus(RbtTaskStatusEnum.DISPATCH.getVal());
//        }
        if(robotTaskMapper.insert(robotTask) == 0) {
            log.error("添加任务失败！" + createReqVO.getRobotSn());
            return null;
        }
        //未执行的任务不用推送消息
        if(!robotTask.getStatus().equals(RbtTaskStatusEnum.UNEXEC.getVal())) {
            rbtRedisDAO.setRobotTask(createReqVO.getRobotSn(),RedisTaskField.TASK,createReqVO.getTaskType());
        }
        return robotTask;
    }

    private String getTaskNo(String robotSn) {
        if(!rbtRedisDAO.hasRobotTaskField(robotSn,RedisTaskField.TASKNO)) {
            return null;
        }
        Object taskNo = rbtRedisDAO.getRobotTask(robotSn,RedisTaskField.TASKNO);
        if(taskNo == null) {
            return null;
        }
        return taskNo.toString();
    }

    private boolean isExitTask(String robotSn) {
        if(StringUtil.isBlank(robotSn)) {
            return false;
        }
        return rbtRedisDAO.hasRobotTaskField(robotSn,RedisTaskField.TASK);
    }

    private boolean validateSameTask(String robotSn, String taskType) {
        if(StringUtil.isBlank(robotSn)) {
            return false;
        }
        if(!rbtRedisDAO.hasRobotTaskField(robotSn,RedisTaskField.TASK)) {
            return false;
        }
        if(rbtRedisDAO.getRobotTask(robotSn,RedisTaskField.TASK).equals(taskType)) {
            return true;
        }
        return false;
    }

    @Override
    public void updateRobotTask(RobotTaskSaveReqVO updateReqVO) {
        // 校验存在
        validateRobotTaskExists(updateReqVO.getId());
        // 更新
        RobotTaskDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDO.class);
        robotTaskMapper.updateById(updateObj);
    }

    @Override
    public void updateRobotTaskStatus(String sn,String taskType,Integer status) {
        updateRobotTaskStatus(sn,taskType,status,null);
    }
    @Override
    public void updateRobotTaskStatus(String sn,String taskType,Integer status,String point) {
        if (StringUtil.isBlank(point)) {
            point = rbtRedisDAO.getPoint(sn);
        }
        if (StringUtil.isBlank(point)) {
            point = "0";
        }
        LambdaQueryWrapper<RobotTaskDO> queryWrapper = new LambdaQueryWrapper<RobotTaskDO>()
                .eq(RobotTaskDO::getRobotSn, sn)
                .eq(RobotTaskDO::getPoint, point)
                .eq(RobotTaskDO::getStatus, status);
        if (StringUtil.isNotBlank(taskType)) {
           queryWrapper.eq(RobotTaskDO::getTaskType,taskType);
        }
        RobotTaskDO robotTask = robotTaskMapper.selectOne(queryWrapper);
        if(robotTask != null) {
            if(status.equals(0)) {
                robotTask.setStartTime(LocalDateTime.now());
                robotTask.setStatus(1);
            } else if(status.equals(1)) {
                robotTask.setEndTime(LocalDateTime.now());
                robotTask.setStatus(10);
            } else {
                return;
            }
            robotTaskMapper.updateById(robotTask);
//            rbtRedisDAO.setRobotTask(robotTask);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRobotTask(Long id) {
        // 校验存在
        RobotTaskDO robotTaskDO = validateRobotTaskExists(id);
        if(robotTaskDO.getStatus() > 0) {
            throw exception(RBT_ROBOT_TASK_DELETE_FAIL_APPROVE,robotTaskDO.getTaskNo());
        }
    }

    @Override
    public void deleteRobotTaskListByIds(List<Long> ids) {
        // 删除
        robotTaskMapper.deleteByIds(ids);
    }

    private RobotTaskDO validateRobotTaskExists(Long id) {
        RobotTaskDO taskDO = robotTaskMapper.selectById(id);
        if (taskDO == null) {
            throw exception(RBT_DATA_NOT_EXISTS);
        }
        return taskDO;
    }

    @Override
    public RobotTaskDO getRobotTask(Long id) {
        return robotTaskMapper.selectById(id);
    }

    @Override
    public PageResult<RobotTaskDO> getRobotTaskPage(RobotTaskPageReqVO pageReqVO) {
        return robotTaskMapper.selectPage(pageReqVO);
    }

}